#pragma once

#include <map>
#include <mutex>
#pragma warning(disable:4251)

namespace qb{

	template<typename Key, typename Val>
	class ThreadSafeMap
	{
		typedef typename std::map<Key, Val>::iterator iterator;
		typedef typename std::map<Key, Val>::const_iterator const_iterator;
		typedef typename std::map<Key, Val>::reverse_iterator reverse_iterator;
		typedef typename std::map<Key, Val>::const_reverse_iterator const_reverse_iterator;
		typedef typename std::map<Key, Val>::size_type size_type;
	public:
		Val& operator [](const Key& key) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_[key]; }
		
		iterator find(const Key& key) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.find(key); }
		const_iterator find(const Key& key) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.find(key);}

		iterator begin(void) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.begin(); }
		const_iterator begin(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.begin(); }

		iterator end(void) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.end(); }
		const_iterator end(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.end(); }

		reverse_iterator rbegin(void) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.rbegin(); }
		const_reverse_iterator rbegin(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.rbegin(); }

		reverse_iterator rend(void) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.rend(); }
		const_reverse_iterator rend(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.rend(); }

		size_type size(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.size(); }
		size_type max_size(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.max_size(); }

		bool empty(void) const { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.empty(); }
		int erase(const Key& key) { std::lock_guard<std::mutex> lk(mtx_); return dataMap_.erase(key); }

	private:
		std::map<Key, Val> dataMap_;
		std::mutex mtx_;
	};

}//namespace qb;
